package lyx.game
{
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	
	import lyx.game.control.IKeyControlTarget;
	import lyx.game.control.KeyBoardController;
	import lyx.game.element.GameElement;
	import lyx.game.locator.ElementLocator;
	import lyx.game.stage.GameStage;
	import lyx.game.utils.Direction;
	import lyx.game.utils.KeySetting;
	import lyx.game.utils.KeyState;
	import lyx.tank.element.AITank;
	import lyx.tank.element.Bullet;
	import lyx.tank.element.PlayerTank;
	import lyx.tank.element.Tank;
	import lyx.tank.element.TankBase;
	import lyx.tank.gamelevel.GameLevelInfo_1;
	import lyx.tank.gamelevel.LevelInfo;
	import lyx.tank.logic.BulletLogic;
	import lyx.tank.logic.TankLogic;
	import lyx.tank.stages.GameOverStage;
	import lyx.tank.stages.GameingStage;
	import lyx.tank.stages.LevelInStage;
	import lyx.tank.stages.LevelOutStage;
	import lyx.tank.stages.StartMenuStage;

	public class GameEngine implements IKeyControlTarget
	{
		static private var _instance:GameEngine;
		
		private var _current_level:LevelInfo;
		private var _tank_logic:TankLogic = new TankLogic();
		private var _bullet_logic:BulletLogic = new BulletLogic();
		
		private var _thread_timer:Timer;
		
		private var _player_tank:PlayerTank;
		private var _waiting_ai_tank:Tank;
		private var _tank_base:TankBase;
		private var _time:int=0;
		
		private var _level_infos:Object = {
			"1":GameLevelInfo_1
			
		};
		
		public function GameEngine()
		{
			_thread_timer = new Timer(50);
			_thread_timer.addEventListener(TimerEvent.TIMER,gameThreadHandler);
		}
		
		static public function getInstance():GameEngine
		{
			if(_instance==null)
			{
				_instance = new GameEngine();
			}
			return _instance;
		}
		
		public function actionByKeysState(state:KeyState,keyset:KeySetting):void
		{
			if(state.last_is_keydown)
			{
				var key:int = state.last_keycode;
				switch(key)
				{
					case keyset.start:
						if(_thread_timer.running)
						{
							_thread_timer.stop();
							var player_control_index:int = KeyBoardController.getInstance().control_targets.indexOf(_player_tank);
							if(player_control_index!=-1)
							{
								KeyBoardController.getInstance().control_targets.splice(player_control_index,1);
							}
						}
						else
						{
							_time = 0;
							_thread_timer.start();
							if(KeyBoardController.getInstance().control_targets.indexOf(_player_tank)==-1)
							{
								KeyBoardController.getInstance().control_targets.push(_player_tank);
							}
						}
						break;
					case keyset.select:
						
						break;
					case keyset.function_0:
						
						break;
				}
			}
		}
		
		public function startEngine(level_info:LevelInfo):void
		{
			_current_level = level_info;
			var info_data:XML = _current_level.data;
			
			var birthplace_data:XMLList = info_data.birthplace;
			_player_tank = new PlayerTank(birthplace_data.playertank.@x,birthplace_data.playertank.@y);
			_player_tank.active_area = new Rectangle(0,0,480,480);
			_player_tank.direction = Direction.NORTH;
			ElementLocator.GAME_ELEMENTS.push(_player_tank);
			KeyBoardController.getInstance().control_targets.push(_player_tank);
			
			for each(var element_info:XML in info_data.elements.game_element)
			{
				var class_name:String = element_info.@class_name;
				var element_class:Class = _current_level.getElementDefinition(class_name);
				var game_element:GameElement = new element_class();
				game_element.x = element_info.@x;
				game_element.y = element_info.@y;
				ElementLocator.GAME_ELEMENTS.push(game_element);
				if(game_element is TankBase)
				{
					_tank_base = game_element as TankBase;
				}
			}
			
			KeyBoardController.getInstance().control_targets.push(this);
			_thread_timer.start();
		}
		
		private function gameThreadHandler(event:TimerEvent):void
		{
			var time:int = getTimer();
			_time = time - _time;
			
			if(KeyBoardController.getInstance().control_targets.indexOf(_player_tank)==-1)
			{
				KeyBoardController.getInstance().control_targets.push(_player_tank);
			}
			
			if(_waiting_ai_tank==null)
			{
				_waiting_ai_tank = new AITank();
				_waiting_ai_tank.active_area = new Rectangle(0,0,480,480);
			}
			
			var info_data:XML = _current_level.data;
			var birthplace_data:XMLList = info_data.birthplace;
			
			var birthplace_blocked:Boolean = false;
			
			for each(var element:GameElement in ElementLocator.GAME_ELEMENTS)
			{
				if(element is Tank)
				{
					_tank_logic.handle(_time,element,ElementLocator.GAME_ELEMENTS);
					for each(var xml:XML in birthplace_data.aitank)
					{
						_waiting_ai_tank.x = int(xml.@x)-5;
						_waiting_ai_tank.y = int(xml.@y)+5;
						birthplace_blocked = _waiting_ai_tank.hitTest(element);
						_waiting_ai_tank.x = int(xml.@x);
						_waiting_ai_tank.y = int(xml.@y);
						if(birthplace_blocked)
						{
							break;
						}
					}
				}
				else if(element is Bullet)
				{
					_bullet_logic.handle(_time,element,ElementLocator.GAME_ELEMENTS);
				}
			}
			
			if(!birthplace_blocked)
			{
				ElementLocator.GAME_ELEMENTS.push(_waiting_ai_tank);
				_waiting_ai_tank = null;
			}
			
			var length:int = ElementLocator.GAME_ELEMENTS.length;
			for(var i:int=0;i<length;i++)
			{
				var item:GameElement = ElementLocator.GAME_ELEMENTS[i];
				if(item.life==0)
				{
					ElementLocator.GAME_ELEMENTS.splice(i,1);
					length--;
					i--;
				}
			}
			
			if(_player_tank.life==0||_tank_base.life==0)
			{
				
			}
			
			_time = time;
		}
		
		public function switchGameStage(stage_class:Class,info:Object=null):void
		{
			switch(stage_class)
			{
				case StartMenuStage:
					startMenuStageHandler(info);
					break;
				case LevelInStage:
					levelInStageHandler(info);
					break;
				case GameingStage:
					gameingStageHandler(info);
					break;
				case LevelOutStage:
					levelOutStageHandler(info);
					break;
				case GameOverStage:
					gameOverStageHandler(info);
					break;
			}
		}
		
		private function startMenuStageHandler(info:Object):void
		{
			var game_stage:StartMenuStage = new StartMenuStage();
			World.getInstance().setCurrentStage(game_stage);
		}
		
		private function levelInStageHandler(info:Object):void
		{
			var game_stage:LevelInStage = new LevelInStage();
			game_stage.level_name = info.level_name;
			World.getInstance().setCurrentStage(game_stage);
		}
		
		private function gameingStageHandler(info:Object):void
		{
			var game_stage:GameingStage = new GameingStage();
			var game_info:Object = {};
			var level_class:Class = _level_infos[info.level_name];
			game_info.level_info = new level_class();
			game_stage.init(game_info);
			World.getInstance().setCurrentStage(game_stage);
		}
		
		private function levelOutStageHandler(info:Object):void
		{
			var game_stage:LevelOutStage = new LevelOutStage();
			World.getInstance().setCurrentStage(game_stage);
		}
		
		private function gameOverStageHandler(info:Object):void
		{
			var game_stage:GameOverStage = new GameOverStage();
			World.getInstance().setCurrentStage(game_stage);
		}
	
	
		
	}
}